﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using OPM.Class;
using OPM.Models;

namespace OPM.Controllers
{
    public class TimelineController : Controller
    {
        private static List<TimeLineCache> TimeLineCaches = new List<TimeLineCache>();

        public ActionResult Index()
        {
            var timelineCache = GetTimelineCache();
            var timeline = timelineCache.TimeLines;

            return View(timeline);
        }

        [HttpGet]
        public ActionResult TimeLineSource(string id)
        {
            if (string.IsNullOrWhiteSpace(U.officer_id))
            {
                ViewBag.CaseId = id;
                ViewBag.timline = new GetTimelineHeader();
                ViewBag.Count = 0;
                ViewBag.timelineOperating = new TimelineOperating[0];

                return View();
            }

            var timelineCacheMe = GetTimelineCache();
            var operating = WSO.GetTimelineOperating(U.Token, id, 0, 30);

            ViewBag.CaseId = id;
            ViewBag.timline = timelineCacheMe.TimeLines.First(o => o.case_id == id);
            ViewBag.Count = operating.Count();
            ViewBag.timelineOperating = operating;

            return View();
        }

        // คลาส cache สำหรับเก็บข้อมูลที่จำเป็นในการเรียกข้อมูล timeline ไปใช้ซ้ำด้วยเงื่อนไขเวลา
        private class TimeLineCache
        {
            public string OfficerId { get; set; }
            public List<GetTimelineHeader> TimeLines { get; set; }
            public DateTime RetrievedDateTime { get; set; }
            public TimeLineCache(string officerId)
            {
                OfficerId = officerId;
                // ใส่ไปว่าโหลดมา 100 วินาทีแล้ว ทำให้ข้อมูลต้องถูกโหลดใหม่แน่นอน
                RetrievedDateTime = DateTime.Now.AddSeconds(-100);
                TimeLines = new List<GetTimelineHeader>();
            }
            public void Update(List<GetTimelineHeader> timelines)
            {
                TimeLines = timelines;
                RetrievedDateTime = DateTime.Now;
            }
            public bool IsOutDate
            {
                get
                {
                    return DateTime.Now.Subtract(this.RetrievedDateTime).TotalSeconds > 10;
                }
            }
        }

        // ทำเพื่อลดเวลาโหลดเพจ Timeline ในหัวข้อย่อย โดยจะจัดเก็บเคช Timeline Header @1000 แรก 
        // ผูกไปกับ  1 user เป็นเวลา 10 วินาที (timeline แต่ละ block ที่โหลดจะเร็วขึ้น)
        [NonAction]
        private TimeLineCache GetTimelineCache()
        {
            if (TimeLineCaches.All(o => o.OfficerId != U.officer_id))
            {
                // ไม่มี object ของ user นี้ อยู่ใน array, ทำการเริ่มต้นใส่ค่าให้
                TimeLineCaches.Add(new TimeLineCache(U.officer_id));
            }

            // มั่นใจแล้วว่า มี object ของ user นี้แล้วแน่นอน จึงดึง first
            var timeLineCache = TimeLineCaches.First(o => o.OfficerId == U.officer_id);

            // ถ้าข้อมูลที่ดึงมาจาก service จริง ครั้งก่อนเก่าเกินกว่า 10 วินาที จะทำการโหลดใหม่, ถ้าไม่ ก็เอาค่าที่ดึงได้จากตัวแปร static คืนไปใช้งานได้เลย
            if (timeLineCache.IsOutDate)
            {
                timeLineCache.Update(WSO.GetTimelineHeader(U.Token, "", "A", 0, 1000).ToList());
            }

            return timeLineCache;
        }

        public ActionResult TimeLineDetail(string id)
        {
            var viewcase = WSO.GetCase(U.Token, id);
            var operating = WSO.GetTimelineOperating(U.Token, id, 0, 10);
            var timelineOperating = new List<TimelineOperating>();
            var getcase = new List<GetCase>();

            getcase.Add(new OPM.Models.GetCase
            {
                ref_code = viewcase.ref_code,
                terminal_type_id = viewcase.terminal_type_id,
                date_closed = viewcase.date_closed,
                summary_result = viewcase.summary_result,
                summary_result_by = viewcase.summary_result_by,
                summary_result_by_text = viewcase.summary_result_by_text,
                channel_incoming_id = viewcase.channel_incoming_id,
                call_backnull = viewcase.call_backnull,
                channel_outgoing_id = viewcase.channel_outgoing_id,
                customer = viewcase.customer,
                org_text = viewcase.org_text,
                case_org_status_text = viewcase.case_org_status_text,
                case_org_summary_result = viewcase.case_org_summary_result,
                detail = viewcase.detail,
                date_occurrenced_from = viewcase.date_occurrenced_from,
                date_occurrenced_to = viewcase.date_occurrenced_to,
                case_area = viewcase.case_area,
                case_code = viewcase.case_code,
                case_id = viewcase.case_id,
                objective_id = viewcase.objective_id,
                objective_text = viewcase.objective_text,
                type_id = viewcase.type_id,
                type_text = viewcase.type_text,
                status_id = viewcase.status_id,
                status_text = viewcase.status_text,
                summary = viewcase.summary,
                defendant = viewcase.defendant,
                date_opened = viewcase.date_opened,
                time_occurrenced = viewcase.time_occurrenced,
                country_id = viewcase.country_id,
                subdistrict_id = viewcase.subdistrict_id,
                subdistrict_text = viewcase.subdistrict_text,
                district_id = viewcase.district_id,
                district_text = viewcase.district_text,
                province_id = viewcase.province_id,
                province_text = viewcase.province_text,
                postcode = viewcase.postcode,
                latitude = viewcase.latitude,
                longitude = viewcase.longitude,
                case_value = viewcase.case_value,
                severity_id = viewcase.severity_text,
                severity_text = viewcase.severity_text,
                priority_id = viewcase.priority_id,
                priority_text = viewcase.priority_text,
                secret_id = viewcase.secret_id,
                secret_text = viewcase.secret_text,
                is_secret = viewcase.is_secret,
                remark = viewcase.remark,
                tq_key = viewcase.tq_key,
                created = viewcase.created,
                created_by = viewcase.created_by,
                created_by_text = viewcase.created_by_text,
                updated = viewcase.updated,
                updated_by = viewcase.updated_by,
                updated_by_text = viewcase.updated_by_text

            });


            foreach (var detail in operating)
            {
                timelineOperating.Add(new TimelineOperating
                {
                    id = detail.id,
                    case_id = detail.case_id,
                    line = detail.line,
                    operating_code = detail.operating_code,
                    is_contact = detail.is_contact,
                    operating_type_id = detail.operating_type_id,
                    operating_type_text = detail.operating_type_text,
                    status_id = detail.status_id,
                    status_text = detail.status_text,
                    operating_date = detail.operating_date,
                    org_id = detail.org_id,
                    org_text = detail.org_text,
                    officer_id = detail.officer_id,
                    officer_text = detail.officer_text,
                    is_received = detail.is_received,
                    image_base_64 = detail.image_base_64
                });
            }

            ViewBag.viewcase = getcase;
            ViewBag.timelineOperating = timelineOperating;

            return View();
        }

        //ระดับชั้นความสำคัญ
        public void Priority()
        {
            var listOfPriority = WSL.GetPriority();
            ViewBag.listOfPriority = new SelectList(listOfPriority, "VAL", "TEXT");
        }

        //ระดับชั้นความลับ 
        public void Secret()
        {
            var listOfSecret = WSL.GetSecret();
            ViewBag.listOfSecret = new SelectList(listOfSecret, "VAL", "TEXT");
        }

        //ระดับชั้นความเร่งด่วน 
        public void Severity()
        {
            var listOfSeverity = WSL.GetSeverity();
            ViewBag.listOfSeverity = new SelectList(listOfSeverity, "VAL", "TEXT");
        }
    }
}